#include "packet/GameServerPacketProcess.h"
#include "../../common/protocol.h"
#include "Community/ChannelManager.h"
#include "Character/CharacterManager.h"

GameServerPacketProcess::GameServerPacketProcess()
{
	ADD_FUNCTION( protocol::community::EchoReq, GameServerPacketProcess::echoReq );
	ADD_FUNCTION( protocol::login::IdentifyUserReq, GameServerPacketProcess::identifyUserReq );
	ADD_FUNCTION( protocol::community::CreateChannelReq, GameServerPacketProcess::createChannelReq );
	ADD_FUNCTION( protocol::community::EnterChannelReq, GameServerPacketProcess::enterChannelReq );
	ADD_FUNCTION( protocol::community::LeaveChannelReq, GameServerPacketProcess::leaveChannelReq );
	ADD_FUNCTION( protocol::community::ChatInfoReq , GameServerPacketProcess::chatInfoReq );
	ADD_FUNCTION( protocol::community::ChannelListReq , GameServerPacketProcess::channelListReq );
	ADD_FUNCTION( protocol::community::EnterLobbyReq , GameServerPacketProcess::enterLobbyReq );
	ADD_FUNCTION( protocol::community::ReadyReq , GameServerPacketProcess::readyReq );
	ADD_FUNCTION( protocol::community::KickOutReq , GameServerPacketProcess::kickOutReq );

	ADD_FUNCTION( protocol::game::StartGameReq, GameServerPacketProcess::startGameReq );
	ADD_FUNCTION( protocol::game::StartedGameReq, GameServerPacketProcess::startedGameReq );
}

GameServerPacketProcess::~GameServerPacketProcess()
{
} 

bool GameServerPacketProcess::echoReq( netlib::packet::Packet *packet, netlib::session::Session *session )
{
	SYNC_GET_PACKET_STRING( str );

	SYNC_GET_PACKET( sendPacket );
	sendPacket->ID( protocol::community::EchoAck );

	*sendPacket << ( const char * )str;

	session->send( sendPacket );

	return ( 0 );
}

bool GameServerPacketProcess::identifyUserReq( netlib::packet::Packet *packet, netlib::session::Session *session )
{
	SYNC_GET_PACKET_STRING( strID );
	SYNC_GET_PACKET_STRING( strPassword );

	*packet >> strID >> strPassword;

	Character *character = CharacterManager::getInstance()->newCharacter( session , strID );

	SYNC_GET_PACKET( sendPacket );
	sendPacket->ID( protocol::login::IdentifyUserAck );

	*sendPacket << ( const char * )strID;

	session->send( sendPacket );

	ChannelManager::getInstance()->create( "test", character );

	return ( 0 );
}

bool GameServerPacketProcess::createChannelReq( netlib::packet::Packet *packet, netlib::session::Session *session )
{
	Character *character = ( Character *)session->getPlayer();
	if ( !character ) return ( false );

	SYNC_GET_PACKET_STRING( roomName );
	*packet >> roomName;

	ChannelManager::getInstance()->create( roomName, character );

	return ( true );
}

bool GameServerPacketProcess::enterChannelReq( netlib::packet::Packet *packet, netlib::session::Session *session )
{
	short int channelNumber = -1;
	Character *character = ( Character *)session->getPlayer();
	if ( !character ) return ( false );

	*packet >> channelNumber;

	DWORD errorCode = ChannelManager::getInstance()->enter( channelNumber, character );

	return ( true );
}

bool GameServerPacketProcess::leaveChannelReq( netlib::packet::Packet *packet, netlib::session::Session *session )
{
	Character *character = ( Character * )session->getPlayer();
	if ( !character ) return ( false );

	ChannelManager::getInstance()->leave( character );

	return ( true );
}

bool GameServerPacketProcess::chatInfoReq( netlib::packet::Packet *packet, netlib::session::Session *session )
{
	SYNC_GET_PACKET_STRING( chatInfo );
	*packet >> chatInfo;

	Character *character = ( Character * )session->getPlayer();
	if ( !character ) return ( false );

	Channel *channel = character->getPlayingChannel();
	if ( !channel ) return ( false );

	channel->chatInfoReq( character, chatInfo );

	return ( true );
}

bool GameServerPacketProcess::channelListReq( netlib::packet::Packet *packet, netlib::session::Session *session )
{
	Character *character = ( Character * )session->getPlayer();
	if ( !character ) return ( false );

	ChannelManager::getInstance()->sendGameRoomList( character );
	return ( true );
}

bool GameServerPacketProcess::enterLobbyReq( netlib::packet::Packet *packet, netlib::session::Session *session )
{
	Character *character = ( Character * )session->getPlayer();
	if ( !character ) return ( false );

	ChannelManager::getInstance()->enterLobby( character );
	return ( true );
}

bool GameServerPacketProcess::readyReq( netlib::packet::Packet *packet, netlib::session::Session *session )
{
	Character *character = ( Character * )session->getPlayer();
	if ( !character ) return ( false );
	GameRoom *gameRoom = character->getPlayingGameRoom();
	if ( !gameRoom ) return ( false );

	bool ready = 0;
	*packet >> ready;

	gameRoom->readyUser( character, ready );
	return ( true );

}

bool GameServerPacketProcess::kickOutReq ( netlib::packet::Packet *packet, netlib::session::Session *session )
{
	Character *character = ( Character * )session->getPlayer();
	if ( !character ) return ( false );
	GameRoom *gameRoom = character->getPlayingGameRoom();
	if ( !gameRoom ) return ( false );

	SYNC_GET_PACKET_STRING( userID );
	*packet >> userID;

	gameRoom->kickOut( character, userID );

	return ( true );

}

bool GameServerPacketProcess::startGameReq( netlib::packet::Packet *packet, netlib::session::Session *session )
{
	Character *character = ( Character * )session->getPlayer();
	if ( !character ) return ( false );
	GameRoom *gameRoom = character->getPlayingGameRoom();
	if ( !gameRoom ) return ( false );

	gameRoom->startGame( character );

	return ( true );
}

bool GameServerPacketProcess::startedGameReq( netlib::packet::Packet *packet, netlib::session::Session *session )
{
	Character *character = ( Character * )session->getPlayer();
	if ( !character ) return ( false );
	GameRoom *gameRoom = character->getPlayingGameRoom();
	if ( !gameRoom ) return ( false );

	gameRoom->startedGame( character );

	return ( true );
}

